home *** CD-ROM | disk | FTP | other *** search
/ Lattice ISP Synario Start… & ISP Encyclopedia 1997 / LATTICE Synario.iso / ispcode / source / icode5a.c next >
Encoding:
C/C++ Source or Header  |  1997-06-24  |  33.4 KB  |  749 lines

  1. /*****************************************************************************
  2. *                            ispCODE5A.c                                     *
  3. * ispCODE for ispLSI Devices Using the Industry Standard ISP State Machine.  *
  4. *              Lattice Semiconductor Corp. Copyright 1996,1997.              *
  5. *                                                                            *
  6. * ISP(tm) daisy chain turbo programming is supported by ispCODE.             *
  7. *                                                                            *
  8. * The function of this ispCODE is to utilize the Industry Standard ISP state *
  9. * machine in the ispLSI devices for programming and verification. The input  *
  10. * file for ispCODE is FULL ispSTREAM files or Super FULL ispSTREAM files.    *
  11. *                                                                            *
  12. * This version of ispCODE is the much simplified version of ispCODE V3.xx    *
  13. * by removing the PES checking, the post BULK ERASE verification and the     *
  14. * simultaneous shifting data in and out. The programming time is thus a bit  *
  15. * longer than V3.xx due to the additional time needed to shift data in and   *
  16. * out separately. It is a very little price to pay for a 50% reduction in    *
  17. * code size which is especially critical for embedded controller programming *
  18. * where resources is extremely limited.                                      *
  19. *                                                                            *
  20. * The file size of Super FULL ispSTREAM is about 30% less than the FULL      *
  21. * ispSTREAM. The saving comes from replacing long chain of 0xFFs with        *
  22. * the number of consecutive 0xFF bytes. For example:                         *
  23. *           0xFF,0xFF,0xFF,0xC3 is reduced to 0xFF,0x03,0xC3                 *
  24. *                                                                            *
  25. * The Super FULL ispSTREAM file is created by the command line program       *
  26. * dld2isp.exe v4.03 with the option sf selected. For example: type           *
  27. *                  dld2isp  design.dld sf                                    *
  28. *                                                                            *
  29. * All ispLSI devices support the Lattice Semiconductor pioneered UES         *
  30. * feature. If the UES is appended into the JEDEC files using the UES editor  *
  31. * on ISP Daisy Chain Download program, the resultant ispSTREAM will take     *
  32. * care of programming and verifying the UES data.                            *
  33. *                                                                             *
  34. * Note: The UES length of most ispLSI devices is the same as their data      *
  35. *       length. If it is found on the data book that they are not the same   *
  36. *       such as ispLSI 3256 and 6192 devices, only the last 160 bits are     *
  37. *       referred to as UES. For example: The data length of ispLSI 3256      *
  38. *       devices is 338 bits and the UES length is 160 bits as shown in the   *
  39. *       data book. Pulse SCLK 338-160=178 times to flush out the phantum     *
  40. *       bits first then read the 1st UES bit.                                *
  41. *                                                                            *
  42. * Revision history:                                                          *
  43. *   5A.000  Howard Tang  10/17/96 Convert from V5.1 to support ISP(tm)       *
  44. *                                 programming using the industry standard ISP*
  45. *                                 state machine with the Super FULL          *
  46. *                                 ispSTREAM.                                 *
  47. *   5A.001  Howard Tang  11/15/96 Change from ispSTREAM from file to         *
  48. *                                 ispSTREAM from ispstream[] array.          *
  49. *   5A.002  Howard Tang  12/20/96 Add Read and Display UES option.           *
  50. *   5A.003  Howard Tang  01/17/97 Update support for GDX devices.            *
  51. *****************************************************************************/
  52.  
  53. #include <stdio.h>
  54. #include <dos.h>
  55. #include <stdlib.h>
  56. #include <string.h>
  57. #include "lattice.h"
  58. #include "istream.hex"   /*5a.001 convert to istream.hex from design.isp by
  59.                                   isp2hex.exe*/
  60.  
  61. /*Global variables */
  62. static short int      bit=0;       /*the current bit read from ispSTREAM*/
  63. static unsigned char curch;        /*the current data from ispSTREAM*/
  64. unsigned char *fp;                 /*the pointer to the ispSTREAM array*/
  65. static short int  inputport=inport1,       /*port address for the input port*/
  66.                   outputport=outport1;      /*port address for the output port*/
  67. static short int      isp_pins=NUL;    /*holds the value of parallel port*/
  68.                                  /*     intialized to drive all pins to LOW*/
  69.  
  70. /*prototypes*/
  71. void            pulse_width(unsigned short int milliseconds);
  72. void            execute(void);
  73. void            move_to_id_state(void);
  74. short int       ispstream_pump(short int operation, short int *end);
  75. void            error_handler(short int rcode, char *message);
  76. unsigned char   GetByte(void);
  77. void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse, 
  78.                          short int *ProgramPulse, short int *RowLength, 
  79.                          unsigned short int *DataSize, 
  80.                          unsigned short int *IDStreamLength);
  81. char ispRead(unsigned short int DataSize, unsigned char *OutData);
  82. void ReadispSTREAMDataSize(unsigned short int  *DataSize);
  83. void ReadispSTREAMData(unsigned short int *DataSize, unsigned char *InData,
  84.                        char SF);
  85. char ispInstruction(char SF,char Send);
  86. void ispData( unsigned char *InData, unsigned short int DataSize);
  87.  
  88. /***************************************************************************
  89.    Function: isp_setpin(byte pins, byte value)
  90.  
  91.    Purpose:
  92.    To apply the specified value to the pins indicated. This routine will
  93.    likely be modified for specific systems. As an example, this code
  94.    is for the PC, as described below.
  95.  
  96.    This routine uses the IBM-PC standard Parallel port, along with the
  97.    schematic shown in Lattice documentation, to apply the signals to the
  98.    programming loop. 
  99.  
  100.    PC Parallel port pin    Signal name
  101.    --------------------    -----------
  102.          2                   out_SDI
  103.          3                   out_SCLK
  104.          4                   out_MODE
  105.          5                   out_ISP
  106.          6                   out_RESET
  107.          7                   DO5
  108.          8                   out_SENSE_CABLE_OUT    
  109.          9                   DO7
  110.          10                  in_SDO
  111.          12                  in_CABLE_SENSE_IN
  112.          15                  in_VCC_OK 
  113.          20                  GND
  114.  
  115.    Parameters:
  116.          - pins, which is actually a set of bit flags (defined in lattice.h) 
  117.            that correspond to the bits of the data port. Each of the I/O port 
  118.            bits that drives an isp programming pin is assigned a flag 
  119.            (through a #define) corresponding to the signal it drives. To 
  120.            change the value of more than one pin at once, the flags are added 
  121.            together, much like file access flags are.
  122.  
  123.            The bit flags are only set if the pin is to be changed. Bits that 
  124.            do not have their flags set do not have their levels changed. The 
  125.            state of the port is always manintained in the static global 
  126.            variable isp_pins, so that each pin can be addressed individually 
  127.            without disturbing the others.
  128.  
  129.          - value, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two
  130.            values are valid. Any non-zero number sets the pin(s) high.
  131.  
  132.    Returns: nothing.
  133.  
  134.  
  135. **************************************************************************/
  136. void isp_setpin(unsigned char pins, unsigned char value)
  137. {
  138.   /* isp_pins is a Global value that keeps track of the current state
  139.      of the pins  */
  140.  
  141.   if( value ) /* set flagged pins HIGH */
  142.       isp_pins = pins | isp_pins;
  143.   else        /* set flagged pins LOW */
  144.       isp_pins = ~pins & isp_pins;
  145.  
  146.   /* value is put on Parallel port pins */
  147.   outp(outputport, isp_pins);
  148.  
  149. } /* isp_setpin() */
  150.  
  151.  
  152. /***************************************************************************
  153.    Function: isp_SDO()
  154.  
  155.    Purpose:
  156.    To get the value of the SDO pin from the input port.
  157.  
  158.    This routine is specific to the PC parallel port setup, but can easily
  159.    be changed to address each user's hardware.
  160.  
  161.    Parameters: none
  162.  
  163.    Returns: The value of SDO, as a byte, with a value of either 0 or 1.
  164.  
  165.    Notes:
  166.    - This routine uses the I/O port addresses contained in the global
  167.      variable inputport, declared in the lattice.h file.
  168.  
  169. ****************************************************************************/
  170. unsigned char isp_SDO(void)
  171. {
  172.  /* MUST return either 0x00 or 0x01 */
  173.   return( (unsigned char) ((inp(inputport) & in_SDO ) ? HIGH : LOW) );
  174.  
  175. } /* isp_SDO() */
  176.  
  177. /*************************************************************
  178. *                                                            *
  179. *                         PULSE_WIDTH                        *
  180. * This procedure produce accurate timing only on straight PC *
  181. * DOS. The timing is not guarantee if use on Windows DOS.    *
  182. * The delay() function is available only from BORLAND.       *
  183. *                                                            *
  184. * Users must devise their own timing procedures to ensure    *
  185. * the specified minimum delay is observed when using         *
  186. * different platform.                                        *
  187. *************************************************************/
  188.  
  189.  
  190. void            pulse_width(unsigned short int milliseconds)
  191. {
  192.                 delay(milliseconds);
  193. }
  194.  
  195.  
  196.  
  197. /*************************************************************
  198. *                                                            *
  199. *                      GETBYTE                               *
  200. * This procedure reads a byte from the ispSTREAM.            *
  201. *************************************************************/
  202. unsigned char GetByte()
  203. {
  204.   /* return (fgetc(fp)); */
  205.   return (*fp++);
  206. }
  207.  
  208.  
  209. /*************************************************************
  210. *                                                            *
  211. *                      SCLOCK                                *
  212. * This procedure apply a clock to TCK.                       *
  213. *************************************************************/
  214. void sclock(void)
  215. {
  216.  isp_setpin(out_SCLK,HIGH);
  217.  isp_setpin(out_SCLK,LOW);
  218. }
  219.  
  220. /*************************************************************
  221. *                                                            *
  222. *                       SHIFT/EXECUTE                        *
  223. *                                                            *
  224. *************************************************************/
  225. void            execute()
  226. {
  227.    isp_setpin(out_MODE, HIGH);
  228.    isp_setpin(out_SDI,  HIGH);
  229.    sclock();
  230.    isp_setpin(out_SDI,  LOW);
  231.    isp_setpin(out_MODE, LOW);
  232. }
  233.  
  234.  
  235. /*************************************************************
  236. *                                                            *
  237. *                      MOVE TO ID STATE                      *
  238. *                                                            *
  239. *************************************************************/
  240.  
  241. void            move_to_id_state()
  242. {
  243.    isp_setpin(out_SDI,LOW);
  244.    isp_setpin(out_MODE, HIGH);    
  245.    isp_setpin(out_MODE, HIGH);   /*extra delay for device to settle*/
  246.    sclock();
  247.    isp_setpin(out_MODE, LOW);
  248. }
  249.  
  250.  
  251. /**********************************************************************
  252. *                                                                     *
  253. *                     READ_ISPSTREAM_HEADER                           *
  254. * Extract the header from the ispSTREAM file.                         *
  255. * Return                                                              *
  256. *     ChainLength--------number of ispLSI devices in the              *
  257. *                        given daisy  chain.                          *
  258. *     ErasePulse---------pulse width in mS for device                 *
  259. *                        bulk erase.                                  *
  260. *     ProgramPulse-------pulse width in mS for device                 *
  261. *                        row by row programming.                      *
  262. *     RowLength----------the number of rows of data +UES              *
  263. *     DataSize-----------the largest size of each row of data.        *
  264. *     BEVend-------------the end of Bulk Erase verify.                *
  265. ***********************************************************************/
  266. void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse, 
  267.                          short int *ProgramPulse, short int *RowLength,
  268.                          unsigned short int *DataSize,
  269.                          unsigned short int *BEVend)
  270. {
  271.    
  272.    *ChainLength = GetByte();              
  273.    *ErasePulse = GetByte() * 0x100;
  274.    *ErasePulse += GetByte();
  275.    *ProgramPulse = GetByte(); 
  276.    *RowLength = GetByte() * 0x100;
  277.    *RowLength += GetByte();
  278.    *DataSize = GetByte() * 0x100;
  279.    *DataSize += GetByte();   
  280.    *BEVend = GetByte() * 0x100;
  281.    *BEVend += GetByte();
  282.    /*End of the header of the ispSTREAM file.*/   
  283.    
  284. }
  285.  
  286. /*********************************************************************
  287. *                                                                    *
  288. *                     READ_ISPSTREAM_DATA_SIZE                       *
  289. * Extract the data size of the current row from the ispSTREAM file.  *
  290. * Return                                                             *
  291. *     DataSize-----------The data bit length of the current row.     *
  292. **********************************************************************/
  293. void ReadispSTREAMDataSize(unsigned short int  *DataSize)
  294. {
  295.  short int index;
  296.  unsigned short int temp;
  297.  unsigned char xch;
  298.  
  299.  xch=0;
  300.  temp = 0;
  301.  for (index=0; index<16; index++)
  302.      {--bit;
  303.       if (bit<0) 
  304.          {
  305.           curch = GetByte();
  306.           bit=7;
  307.          }
  308.       if ((curch >> bit) & 0x01)  xch |= 0x80 >> index%8;                
  309.       if (index%8==7) {temp = temp * 0x100 + xch; xch=0;}
  310.      }  
  311.    *DataSize = temp;   
  312. }
  313.  
  314. /*****************************************************************
  315. *                                                                *
  316. *                     READ_ISPSTREAM_DATA                        *
  317. * Extract the data from the ispSTREAM file.                      *
  318. *     SF-----------------Super FULL ispSTREAM file if true.      *
  319. * Return                                                         *
  320. *     DataSize-----------The number of data bits  fetched.       *
  321. *     InData-------------The data stream from ispSTREAM file     *
  322. ******************************************************************/
  323. void ReadispSTREAMData(unsigned short int  *DataSize, unsigned char *InData,
  324.                        char SF)
  325. {
  326.  unsigned short int index,size;
  327.  short int j;
  328.  unsigned char xch;
  329.  short int FFcount=0;
  330.  
  331.  ReadispSTREAMDataSize(&size);
  332.  if (size > 0)  /*5a.003 retain the old size if the current row is NULL*/
  333.     *DataSize = size; 
  334.  j=0;
  335.  xch=0;
  336.  for (index=0; index<size; index++)
  337.      {--bit;
  338.       if (bit<0) 
  339.          {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
  340.              { curch = GetByte(); 
  341.                if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
  342.                FFcount = GetByte();     /*The number of 0xFF bytes*/
  343.              }
  344.           else FFcount--; /*Use up the 0xFF chain first*/
  345.           bit=7;
  346.          }
  347.       if ((curch >> bit) & 0x01)  xch |= 0x80 >> index%8;                
  348.       if (index%8==7) {InData[j++] = xch; xch=0;}
  349.      }  
  350.    if (size > 0) InData[j] = xch;   /*save the last byte of the current row*//*5a.003*/
  351. }
  352.  
  353. /*****************************************************************
  354. *                                                                *
  355. *                     ispInstruction                             *
  356. * Extract the instruction from the ispSTREAM file and clock into *
  357. * the devices or throw away.                                     *
  358. *     SF-----------------Super FULL ispSTREAM file if true.      *
  359. *     Send---------------Send data to devices if true.           *
  360. * Return                                                         *
  361. *     NONE                                                       *
  362. ******************************************************************/
  363. char ispInstruction(char SF, char Send)
  364. {
  365.  short int index;
  366.  short int i;
  367.  unsigned short int size;
  368.  short int FFcount=0;
  369.  
  370.  ReadispSTREAMDataSize(&size);
  371.  for (index=0; index<size; index++)
  372.      {--bit;
  373.       if (bit<0) 
  374.          {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
  375.              { curch = GetByte(); 
  376.                if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
  377.                FFcount = GetByte();     /*The number of 0xFF bytes*/
  378.              }
  379.           else FFcount--; /*Use up the 0xFF chain first*/
  380.           bit=7;
  381.          }
  382.       if (Send) /*send the data to the devices*/
  383.          {isp_setpin(out_SDI,(curch >> bit) & 0x01);
  384.           sclock();  /*clock the data into the command registers */
  385.          }
  386.      }
  387.  if ((Send)&&(size > 0)) 
  388.     {execute();  /*execute the instruction if sent*/
  389.      return (1); /*signify data or instruction has actually sent*/
  390.     }
  391.  else return (0); /*no data or instruction send to the devices*/
  392. }
  393.  
  394. /**********************************************************************
  395. *                                                                     *
  396. *                     ispData                                         *
  397. * Send the data stream to devices.                                    *
  398. *    InData-----------The data stream to be sent to devices.          *
  399. *    DataSize---------The length of the data stream.                  *
  400. ***********************************************************************/
  401. void ispData(unsigned char *InData,unsigned short int DataSize)
  402. {
  403.  unsigned short int index;
  404.  short int j;
  405.  unsigned char curch;
  406.  
  407.  j=0;
  408.  for (index = 0; index <DataSize; index++) { 
  409.       if (index%8==0) curch = InData[j++];
  410.       isp_setpin(out_SDI, (((curch << index%8) & 0x80) ? 0x01 : 0x00)); 
  411.       sclock();  /*clock data into the data shift registers */
  412.       }
  413.  if (DataSize > 0) execute();   /*step to shift state*//*5a.003*/ 
  414. }
  415.  
  416. /**********************************************************************
  417. *                                                                     *
  418. *                     ispRead                                         *
  419. * Read the data stream from devices and verify.                       *
  420. *    DataSize---------The length of the data stream.                  *
  421. *    OutData----------The data stream to be compare with those read   *
  422. *                     from devices.                                   *
  423. ***********************************************************************/
  424. char ispRead(unsigned short int DataSize, unsigned char *OutData)
  425. {
  426.  unsigned short int index,error;
  427.  unsigned char xch,cur_bit;
  428.  short int j;
  429.  
  430.  j=0;
  431.  error=0;
  432.  xch=0;
  433.  for (index = 0; index <DataSize; index++) { 
  434.       if (index%8==0) xch = OutData[j++];
  435.       cur_bit=isp_SDO(); 
  436.       if (cur_bit != (((xch << index%8) & 0x80) ? 0x01 : 0x00)) error++;  
  437.       sclock();  /*clock data out from the data shift registers */
  438.       }
  439.  execute();   /*step to shift state*/ 
  440.  if (error > 0) return 1;      /*Flag failure occur*/
  441.  else return (OK);
  442. }
  443.  
  444.  
  445. /**********************************************************************
  446. *                                                                     *
  447. *                     ispDisplay                                      *
  448. * Read the data stream from devices and display                       *
  449. *    DataSize---------The length of the data stream.                  *
  450. *    OutData----------The data stream read from devices.              *
  451. *                                                                     *
  452. * This function is for reading and displaying the UES of the ispLSI   *
  453. * devices. If the JEDEC file of the ispLSI devices containing UES     *
  454. * data, the UES data in the ispLSI devices will be read and displayed *
  455. * when calling this function. For example:                            *
  456. *                    1032E pv 1032e.jed                               *
  457. *                    2096  pv 2096.jed                                *
  458. *                    3256A pv 3256a.jed                               *
  459. * If only the JEDEC files 1032e.jed and 2096.jed files have UES data  *
  460. * then the UES data of 1032E and 2096 will be read and displayed as a *
  461. * continuous UES string. Please note that the UES of ispGAL22v10 and  *
  462. * ispGDS can't supported by this function due to the fact that the UES*
  463. * are part of the ARRAY of those devices. Please also note that the   *
  464. * actual length of UES row can be longer than what is published.      *
  465. * For example: The UES row of 3256a is actually 338 bits long whereas *
  466. * the published UES length is 160. The extra bits are filled with 1s  *
  467. * by the ispSTREAM writter.  This function can read and display only  *
  468. * the full length of the UES row. It can't mask out the dummy bits.   *
  469. * It is strongly recommended that only one device is selected in a    *
  470. * time in a daisy chain for reading and displaying UES.               *
  471. ***********************************************************************/
  472. char ispDisplay(unsigned short int DataSize, unsigned char *OutData)
  473. {
  474.  unsigned short int index;
  475.  unsigned char xch,cur_bit;
  476.  unsigned short int j;
  477.  j=0;
  478.  xch=0;
  479.  for (index = 0; index <DataSize; index++) { 
  480.       cur_bit=isp_SDO(); 
  481.       if (cur_bit) xch |= (0x80 >> index%8);
  482.       if (index%8==7) {OutData[j++] = xch;
  483.                        xch=0;}
  484.       sclock();  /*clock data out from the data shift registers */
  485.       }
  486.  OutData[j] = xch; /*store the last byte*/
  487.    printf("\nThe UES string in HEX:\n");
  488.    for (index = 0; index < DataSize/8; index++)
  489.        printf("%02x",OutData[index]);
  490.    printf("\nThe UES string in ASCII:\n");
  491.    for (index = 0; index < DataSize/8; index++)
  492.        {if (isprint(OutData[index])) printf("%c",OutData[index]);
  493.         else printf(".");
  494.        }
  495.    printf("\n");
  496.  execute();   /*step to shift state*/ 
  497.  return (OK);
  498. }
  499.  
  500. /*************************************************************
  501. *                                                            *
  502. *                     ISPSTREAM_PUMP                         *
  503. *                                                            *
  504. *************************************************************/
  505.  
  506. short int   ispstream_pump(short int operation, short int *end)
  507. {
  508.    register short int    row;
  509.    char            SF;                    /*ispSTREAM file types identifier*/
  510.    char            send;                  /*send data to devices if true*/
  511.    char            ready;                 /*5a.003 ready to verify data*/
  512.    unsigned char   FileType;
  513.    short int       last_row,
  514.                    erase_pulse,
  515.                    program_pulse,
  516.                    devices_in_chain;
  517.    unsigned short int    maxi_data,
  518.                    data_length,
  519.                       be_row;
  520.    short int       rcode,condition;
  521.    unsigned char   *buf;
  522.  
  523.    row =0;
  524.    bit = 0;
  525.    /*Start reading the header of the ispSTREAM */
  526.    fp = ispstream;                            /*5a.1 point to the ispSTREAM*/ 
  527.    FileType = GetByte();
  528.    if (FileType == 0x0F) {SF=false;}          /*Check for correct file type*/
  529.    else if (FileType == 0x0a ) {SF=true;}     /*Super FULL ispSTREAM file found*/ 
  530.    else {
  531.         return FILE_NOT_JEDEC;
  532.        }
  533.    ReadispSTREAMHeader(&devices_in_chain, &erase_pulse, &program_pulse,
  534.                            &last_row, &maxi_data, &be_row);
  535.  
  536.    rcode = OK;                                /*Success by default.*/
  537.    if ((operation==verify)||
  538.        (operation==verify_ues)||
  539.        (operation==read_show_ues))          /*verify only*/
  540.       {erase_pulse=0;                       /*void the erase instruction*/ 
  541.        program_pulse=0;                     /*void the program instruction*/
  542.       }
  543.    
  544.    /*Allocate memory to store one row of data from the ispSTREAM file.*/
  545.      buf = buffer;   /*5a.1 use the array declared in istream.hex*/
  546.  
  547.    /*set the initial condition of the parallel port*/
  548.    /*     All the port_pins defined on lattice.h will be controlled by
  549.           ispstream_pump(). The rest can be initialized here either to
  550.           HIGH or LOW and won't be altered by isptream_pump*/
  551.             
  552.    isp_pins = NUL;          /* intialize to drive all port pins LOW*/
  553.    isp_setpin(out_ISP, LOW);/*  drive ispEN pin low to enable the 
  554.                                    ISP controlling pins:
  555.                                    SCLK,MODE,SDI and SDO.*/ 
  556.    move_to_id_state();      /* Go to Idle state*/
  557.    execute();               /* synchronize the ISP state machine*/
  558.    move_to_id_state();       /*Load the IDs*/
  559.    ReadispSTREAMData(&data_length,buf,SF);   /*fetch ID stream from ispSTREAM*/
  560.    rcode = ispRead(data_length,buf);            /*verify the ID stream*/    
  561.    if (rcode != OK)     
  562.       {
  563.        return UNKNOWN_CHIP;      
  564.       } 
  565.    for (row=1; row<be_row; row++)   
  566.        {switch(row)
  567.          { case 8: if (erase_pulse > 0)             /*erase the devices*/
  568.                     {
  569.                      ispInstruction(SF,true);
  570.                      sclock();                    /*start the erase timing*/
  571.                      pulse_width(erase_pulse);    /*erase pulse*/
  572.                      isp_setpin(out_MODE, HIGH);
  573.                      isp_setpin(out_SDI,HIGH);
  574.                      pulse_width(1);              /*super voltage discharge*/
  575.                      sclock();
  576.                      isp_setpin(out_SDI,LOW);
  577.                      isp_setpin(out_MODE,LOW);    /*devices in shift state*/
  578.                     }
  579.                   else ispInstruction(SF,false); /*skipp BULK ERASE*/
  580.                  break;
  581.          default:if (((row-9)%12==3)||((row-9)%12==8)) /*skipp BULK ERASE verify*/
  582.                     ReadispSTREAMDataSize(&data_length);         
  583.                  else ispInstruction(SF,false);    
  584.                  break;}
  585.        }
  586.    /*start processing the rows in the ispSTREAM file*/
  587.    data_length = 0;
  588.    for (; row <= last_row; row++) {
  589.        *end = row;                               /* The row number where process ended.*/
  590.        if (row==last_row) condition = 8;         /* security programming*/
  591.        else condition = (row-9) % 12;
  592.        if (((operation==verify_ues)||(operation==read_show_ues))
  593.            &&(row <= last_row-DATAROW)) send = false;
  594.        else send = true;
  595.        switch(condition){
  596.            case 0:                              /*address shift*/
  597.            case 1:ispInstruction(SF,send);      /*address data*/
  598.                   break;
  599.            case 2:                              /*data shift*/
  600.            case 7:ready=ispInstruction(SF,send);   /*5a.003 data shift*/
  601.                   break;
  602.            case 3:                              /*shift data in/out of devices*/
  603.            case 8:
  604.                   if ((data_length > 0)&&(ready))  /*5a.003 verify the data shifted in*/
  605.                      {rcode = ispRead(data_length,buf);   
  606.                       execute(); /*back to execute state*/
  607.                       data_length=0;               /*5a.003 data verified*/
  608.                      }
  609.                   ReadispSTREAMData(&data_length,buf,SF); /*fetch data stream from ispSTREAM*/
  610.                   if (ready) ispData(buf,data_length);  /*send data into devices*/
  611.                   break;
  612.            case 4:
  613.            case 9:if (program_pulse > 0)        /*program and verify*/
  614.                      {
  615.                       if (ispInstruction(SF,true))     /*5a.003 program commands exist*/
  616.                          {sclock();                       /*start program timing*/
  617.                           pulse_width(program_pulse);
  618.                           execute();                      /*step to shift state*/
  619.                          }
  620.                      }
  621.                   else ispInstruction(SF,false);   /*skip programming*/
  622.                   break;
  623.            case 5:
  624.           case 10:if(ispInstruction(SF,send))         /*verify*/
  625.                     {sclock();                           /*start verify timing*/
  626.                      pulse_width(1);                     /*30uS min. verify time*/
  627.                      execute();                          /*step to shift state*/
  628.                     }
  629.                   break;
  630.            case 6:
  631.           case 11:if (ispInstruction(SF,send))
  632.                   {   
  633.                       if (operation==read_show_ues)     /*5A.002 read and display ues*/
  634.                          rcode = ispDisplay(data_length,buf);
  635.                       else 
  636.                       rcode = ispRead(data_length,buf);   /*verify the data stream*/
  637.                       data_length=0;                      /*don't verify again*/
  638.                   }
  639.                   break;
  640.           default:break;
  641.          }
  642.        if (rcode != OK)  
  643.          { 
  644.              return VALIDATION_ERROR;      
  645.          }
  646.        }                              
  647.            
  648.    move_to_id_state();        /*activate the ispGAL and ispGDS devices*/
  649.    isp_setpin(out_ISP,HIGH);  /*activate the ispLSI devices*/
  650.    return (OK);
  651.  
  652. }
  653.  
  654.  
  655. /*************************************************************
  656. *                                                            *
  657. *                         error_handler                      *
  658. *                                                            *
  659. *  rcode                  - error code                       *
  660. *                                                            *
  661. *                                                            *
  662. *  This procedure return the address of the message string   *
  663. *  for the corresponding error code.                         *
  664. *                                                            *
  665. *************************************************************/
  666.  
  667. void error_handler(short int rcode, char *message)
  668. {
  669.  
  670. char *error_message[] = {{"PASS"},{""},{""},{"PC Hardware Problem"},{""},
  671.                    {""},{""},
  672.                    {"No Device Found/Open Download Cable/Open Daisy Chain"},
  673.                    {"Can't Find the File"},{""},{"Not Enough PC Memory"},
  674.                    {"Verification Fail"},{""},{""},
  675.                    {""},
  676.                    {"The Chip Count in the Chain and the File Do Not Match"},
  677.                    {"Unknown Device Found"},{"Wrong File Type"},{"File Error"},
  678.                    {""}};
  679.  
  680.  strcpy(message, error_message[-rcode]);
  681.  
  682.  
  683. /*************************************************************
  684. *                                                            *
  685. *                            MAIN                            *
  686. *                                                            *
  687. *************************************************************/
  688.  
  689. short int          main(int argc, char *argv[])
  690. {
  691.    short int       rcode = OK,
  692.                    end = 0;
  693.    char            str[300];   
  694.    short int operation=prog_verify;  /*Default to Program and Verify*/
  695.    
  696.    printf("\n                 Lattice Semiconductor Corp.\n");
  697.    printf("\n             ispCODE V5A.003 Copyright 1996,1997.\n");
  698.    printf("\n              ispSTREAM Driver for ispLSI Devices\n");
  699.    printf("\n  For Daisy Chain of All ISP Devices On LSC ISP Controller\n\n");
  700.  
  701.    if ((argc < 1) || (argc > 2)) {
  702.       printf("\nUsage: sturbo [operation]\n");
  703.       printf("Example: sturbo pv\n");
  704.       printf("\n");
  705.       printf("operation            \"pv\" = Program and verify\n");
  706.       printf("                     \"v\" = Verify only\n");
  707.       printf("                     \"uv\" = Verify UES only\n");
  708.       printf("                     \"ud\" = Read and display UES from devices.\n");
  709.       printf("                     Default to pv if operation is not entered.\n");                            
  710.       exit(1);
  711.    }
  712.  
  713.       if (rcode == OK){        /*start programming and verification*/
  714.                 
  715.           if(!strcmp(strlwr(argv[1]),"uv")){                  /*3.05 What to do? uv=ues verify only*/
  716.               operation=verify_ues;                                      /*for verify ues only =1*/  
  717.               printf("\nStart Verify UES of ispLSI devices.......\n");}  
  718.           else if(!strcmp(strlwr(argv[1]),"ud")){               /*v = verify only*/
  719.               operation=read_show_ues;
  720.               printf("\nStart Read and Display UES of ispLSI devices .......\n");}
  721.           else if(!strcmp(strlwr(argv[1]),"v")){               /*v = verify only*/
  722.               operation=verify;
  723.               printf("\nStart Verify.......\n");}
  724.           else {                                               /*pv = program and verify: Default*/
  725.                   operation=prog_verify;
  726.                   printf("\nStart Program and Verify.......\n");
  727.                }    
  728.  
  729.         rcode = ispstream_pump(operation, &end);       /*3.05 add operation switch*/
  730.        }
  731.    if (rcode != OK) {
  732.       error_handler(rcode, str);
  733.       printf("\nFailed At Row %d in Program and Verify Due To %s\n", end, str);
  734.       printf("\n");
  735.       printf("+-------+\n");
  736.       printf("| FAIL! |\n");
  737.       printf("+-------+\n");
  738.       return (-rcode);
  739.    } else {
  740.       printf("\n");
  741.       printf("+=======+\n");
  742.       printf("| PASS! |\n");
  743.       printf("+=======+\n");
  744.    }
  745.  
  746.    return(0);
  747.